//
//  SierpinskiTriangle_2D.cpp
//  GLDemo
//
//  Created by wenqi on 5/30/14.
//  Copyright (c) 2014 xiewneqi. All rights reserved.
//

#include <stdio.h>
#ifdef __APPLE__
#include <GLUT/glut.h>
#define glGenVertexArrays glGenVertexArraysAPPLE
#define glBindVertexArray glBindVertexArrayAPPLE
#else
#include "GL/glew.h"
#include <GL/glut.h>
#endif

#include "shader_initialize.h"
#include "sierpinski_triangle_point.h"
#include <stdlib.h>
#include "math_tools.h"

const int NumPoints = 10000;
static Point2 points[NumPoints];


GLuint vbos[1];
GLuint vaos[1];

void init_sierpinski_triangle_main (int argc, char** argv)
{
    glutInit (&argc, argv);
    glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB);
    glutInitWindowSize (800, 600);
    glutInitWindowPosition (100, 100);
    glutCreateWindow ("Sierpinski triangles 2D");
    glutDisplayFunc (display_sierpinski_triangle_2d);
    init_sierpinski_triangle_gl ();
    glutMainLoop ();
}

void init_sierpinski_triangle_gl ()
{
    setup_sierpinski_data ();
    
    // 编译Shader
    GLuint shaderProgram = InitShader ("vbo_vao_vertex_shader.glsl", "vbo_vao_fragment_shader.glsl");
    glUseProgram (shaderProgram);
    GLuint posLoc = glGetAttribLocation (shaderProgram, "va_position");
    
    glGenBuffers (1, vbos);
    glGenVertexArrays (1, vaos);
    
    glBindBuffer (GL_ARRAY_BUFFER, vbos[0]);
    glBufferData (GL_ARRAY_BUFFER, sizeof (points), points, GL_STATIC_DRAW);
    glBindVertexArray (vaos[0]);
    glEnableVertexAttribArray (posLoc);
    glBindBuffer (GL_ARRAY_BUFFER, vbos[0]);
    glVertexAttribPointer (posLoc, 2, GL_FLOAT, GL_FALSE, 0, 0);
    
    glClearColor (1, 1, 1, 1);
}

void setup_sierpinski_data ()
{
    Point2 vertices[3] = {
        {-1, -1},
        {0, 1},
        {1, -1}
    };
    points[0] = {0.25f, 0.5f};
    for (int i = 1; i < NumPoints; ++ i)
    {
        int j = rand () % 3;
        points[i] = {
            (points[i - 1].x + vertices[j].x) * 0.5f,
            (points[i - 1].y + vertices[j].y) * 0.5f
        };
    }
}

void display_sierpinski_triangle_2d ()
{
    glClear (GL_COLOR_BUFFER_BIT);
    
    glBindVertexArray (vaos[0]);
    glDrawArrays (GL_POINTS, 0, NumPoints);
    
    glFlush ();
}
